import { onBeforeUnmount, ref, shallowRef } from 'vue';
import * as Cesium from 'cesium';
import { allList2, getColor, getDef, update3dtilesMaxtrix } from './utils';

const useBim = () => {
  const target = ref<HTMLElement | null>(null);
  const viewer = shallowRef<Cesium.Viewer>({} as Cesium.Viewer);
  const tileset = shallowRef<Cesium.Cesium3DTileset>({} as Cesium.Cesium3DTileset);
  const ionTileset = shallowRef<Cesium.Cesium3DTileset>({} as Cesium.Cesium3DTileset);
  const originalIonTransform = shallowRef<Cesium.Matrix4>({} as Cesium.Matrix4);

  /**
   *  初始化viewer
   * @returns
   */
  const initViewer = () => {
    if (!target.value) return;
    viewer.value = new Cesium.Viewer(target.value, {
      timeline: false,
      animation: false,
      geocoder: false,
      homeButton: false,
      sceneModePicker: false,
      baseLayerPicker: false,
      navigationHelpButton: false,
      fullscreenButton: false
      // terrainProvider: new Cesium.CesiumTerrainProvider({
      //   url: 'http://data.marsgis.cn/terrain'
      // })
    });
    // 显示帧率
    viewer.value.scene.debugShowFramesPerSecond = true;
    viewer.value.scene.globe.depthTestAgainstTerrain = true;

    // const handler = new Cesium.ScreenSpaceEventHandler(viewer.value.scene.canvas);
    // handler.setInputAction(movement => {
    //   // const clickPosition = viewer.value!.scene.camera.pickEllipsoid(e.position);
    //   const getCartesianCoordinate = pos => {
    //     //获取点击位置的经纬度
    //     // console.log('pos: ', pos);
    //     const cartesianCoordinate = viewer.value.scene.pickPosition(pos);
    //     if (!cartesianCoordinate) {
    //       return null;
    //     }
    //     const cartographic = Cesium.Cartographic.fromCartesian(cartesianCoordinate); //将笛卡尔坐标转换为地理坐标
    //     const longitude = Cesium.Math.toDegrees(cartographic.longitude);
    //     const latitude = Cesium.Math.toDegrees(cartographic.latitude);
    //     const height = cartographic.height;
    //     const position = {
    //       longitude: Number(longitude.toFixed(6)),
    //       latitude: Number(latitude.toFixed(6)),
    //       altitude: Number(height.toFixed(2))
    //     };
    //     // console.log('坐标: ', position);
    //     return position;
    //   };

    //   const location = getCartesianCoordinate(movement.position);
    //   console.log('location: ', location);
    //   // params.onClickCb(location);
    // }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  };

  /**
   * 加载3Dtiles
   */
  const load = async () => {
    const url1 = `${location.origin}/cesium/anhuiligong/tileset.json`;
    tileset.value = await Cesium.Cesium3DTileset.fromUrl(url1, { ...getDef() });
    viewer.value.scene.primitives.add(tileset.value);
    // 设置场景时间
    viewer.value.clock.currentTime = Cesium.JulianDate.fromDate(new Date(`2025/9/12 12:00:00`));
    tileset.value.root.transform = update3dtilesMaxtrix(117.0238, 32.5875, 0, -50);
    viewer.value.zoomTo(tileset.value);
  };

  async function addIonTileset(floor = 1) {
    ionTileset.value = viewer.value.scene.primitives.add(
      await Cesium.Cesium3DTileset.fromIonAssetId(3515646, { show: true })
    );
    await ionTileset.value.readyPromise.then(tileset => {
      // 添加Ion模型
      viewer.value.scene.primitives.add(tileset);
      originalIonTransform.value = update3dtilesMaxtrix(
        117.033359,
        32.549835,
        0,
        -3 + (floor - 1) * 3.5
      );
      tileset.root.transform = originalIonTransform.value;
    });
  }
  function addClickEvent() {
    const handler = new Cesium.ScreenSpaceEventHandler(viewer.value.canvas);
    handler.setInputAction(movement => {
      const postion = getCartesianCoordinate(movement.position);
      if (!postion) return;
      slideModel(-14);
      addIonTileset(2);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }
  const getCartesianCoordinate = pos => {
    //获取点击位置的经纬度
    // console.log('pos: ', pos);
    const cartesianCoordinate = viewer.value.scene.pickPosition(pos);
    if (!cartesianCoordinate) {
      return null;
    }
    const cartographic = Cesium.Cartographic.fromCartesian(cartesianCoordinate); //将笛卡尔坐标转换为地理坐标
    const longitude = Cesium.Math.toDegrees(cartographic.longitude);
    const latitude = Cesium.Math.toDegrees(cartographic.latitude);
    const height = cartographic.height;
    const position = {
      longitude: Number(longitude.toFixed(6)),
      latitude: Number(latitude.toFixed(6)),
      altitude: Number(height.toFixed(2))
    };
    console.log('当前点击的坐标: ', position);
    return position;
  };

  // 抽屉式滑动动画
  const slideModel = (targetOffsetY = 0) => {
    if (!ionTileset.value || !ionTileset.value.ready) return;

    viewer.value.clock.shouldAnimate = true;

    const startTime = Cesium.JulianDate.now();
    const duration = 0.5; // 动画时长更快更流畅

    // 获取当前变换矩阵（而非原始矩阵）
    const currentTransform = ionTileset.value.root.transform.clone();
    const currentOffset = new Cesium.Cartesian3();
    Cesium.Matrix4.getTranslation(currentTransform, currentOffset);

    function animate() {
      const currentTime = Cesium.JulianDate.now();
      const elapsed = Cesium.JulianDate.secondsDifference(currentTime, startTime);
      const progress = Cesium.Math.clamp(elapsed / duration, 0, 1);
      const easedProgress = Cesium.EasingFunction.QUADRATIC_OUT(progress);

      // 计算当前偏移量（基于当前偏移，Y向）（动画插值公式）
      const currentY = currentOffset.y + (targetOffsetY - currentOffset.y) * easedProgress;

      const offset = new Cesium.Cartesian3(0, currentY, 0);

      // 根据平移向量创建一个平移矩阵（将单位矩阵与平移矩阵相乘）
      const offsetMatrix = Cesium.Matrix4.fromTranslation(offset);
      const newTransform = Cesium.Matrix4.multiply(
        Cesium.Matrix4.IDENTITY, // 使用单位矩阵
        offsetMatrix,
        new Cesium.Matrix4()
      );

      // 应用新变换（保持原始位置+新偏移）
      ionTileset.value.root.transform = Cesium.Matrix4.multiply(
        originalIonTransform.value,
        newTransform,
        new Cesium.Matrix4()
      );

      if (progress >= 1) {
        viewer.value.clock.onTick.removeEventListener(animate);
      }
    }
    viewer.value.clock.onTick.addEventListener(animate);
  };

  const addBoxClassificationPrimitive = () => {
    function addColorBox(item: any) {
      const length = 15,
        width = 3,
        height = 3,
        baseHeight = 1; //楼的长宽高和基地高

      const cartesian3 = Cesium.Cartesian3.fromDegrees(
        item.position[0],
        item.position[1],
        item.position[2]
      );
      // 用Cesium库中的Cartesian3方法将地理坐标（经度、纬度）转换为三维笛卡尔坐标

      for (let i = 0; i < item.detail.length; i++) {
        //用于将一个东-北-上（ENU）坐标系中的点转换到一个固定的笛卡尔坐标系中。这个方法通常用于将飞机或无人机的位置从它们的局部坐标系转换到全局坐标系。
        const modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(cartesian3);
        //根据给定的偏航（Heading）、俯仰（Pitch）和翻滚（Roll）角度创建一个 3x3 旋转矩阵。
        const hprRotation = Cesium.Matrix3.fromHeadingPitchRoll(
          new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(-6), 0.0, 0.0)
        );
        //用于根据旋转和平移向量创建一个 4x4 变换矩阵。这个矩阵可以表示一个物体在空间中的旋转和平移，常用于设置场景中实体的位置和方向。
        const hpr = Cesium.Matrix4.fromRotationTranslation(
          hprRotation,
          new Cesium.Cartesian3(0.0, 0.0, baseHeight + 3 * i) //楼层高度上的偏移
        );

        //旋转矩阵Matrix3
        const mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(85));
        const rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
        Cesium.Matrix4.multiply(modelMatrix, rotationZ, modelMatrix);

        Cesium.Matrix4.multiply(modelMatrix, hpr, modelMatrix);
        const build_no = item.detail[0].attribute.build_no;

        const instance = new Cesium.GeometryInstance({
          geometry: Cesium.BoxGeometry.fromDimensions({
            vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
            dimensions: new Cesium.Cartesian3(length, width, height)
          }),
          modelMatrix: modelMatrix,
          attributes: {
            color: Cesium.ColorGeometryInstanceAttribute.fromColor(getColor(i)),
            show: new Cesium.ShowGeometryInstanceAttribute(true) //设置初始化后是否显示
          },
          id: build_no + '-' + item.unitNum + '-' + `${i + 1}`
        });
        viewer.value.scene.primitives.add(
          new Cesium.ClassificationPrimitive({
            geometryInstances: instance,
            classificationType: Cesium.ClassificationType.CESIUM_3D_TILE //只绘制在3dtiles上
          })
        );
      }
    }

    allList2.forEach(item => addColorBox(item));
  };

  onBeforeUnmount(() => {
    viewer.value?.destroy?.();
  });
  return {
    target,
    viewer,
    tileset,
    initViewer,
    load,
    addClickEvent,
    addIonTileset,
    addBoxClassificationPrimitive
  };
};

export { useBim };
